package com.ruicar.afs.cloud.afscase.channel.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.channel.common.Constants;
import com.ruicar.afs.cloud.afscase.channel.condition.ChannelQuotaCondition;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelBaseInfo;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelQuotaInfo;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelBaseInfoService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelQuotaInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseChannelInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseContractInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseChannelInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseContractInfoService;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyCostDetailsService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.LoanModelEnum;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.QuotaTypeEnum;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: sang jian
 * @date: 2020/8/26 19:02
 * @description:
 */

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/channelQuota")
public class ChannelQuotaController {

    private final ChannelQuotaInfoService channelQuotaInfoService;
    private final ChannelBaseInfoService channelBaseInfoService;
    private final CaseChannelInfoService caseChannelInfoService;
    private final CaseContractInfoService caseContractInfoService;
    private final ApplyCostDetailsService applyCostDetailsService;

    @PostMapping("/getQuotaListByChannelId")
    @ApiOperation(value = "根据渠道id获取额度信息")
    public IResponse getQuotaListByChannelId(@RequestBody ChannelQuotaCondition condition) {

        Assert.notNull(condition.getChannelId(), "渠道id不能为空!");
        List<ChannelQuotaInfo> quotaInfoList = channelQuotaInfoService.list(Wrappers.<ChannelQuotaInfo>query().lambda()
                .eq(ChannelQuotaInfo::getChannelId, condition.getChannelId())
        );
        return IResponse.success(quotaInfoList);
    }

    @PostMapping("/recomputeChannelQuota")
    @ApiOperation(value = "额度重算")
    @Transactional
    public List<ChannelQuotaInfo> recomputeChannelQuota(@RequestBody ChannelQuotaCondition condition) {

        Assert.notNull(condition.getChannelId(), "渠道id不能为空!");
        Assert.notNull(condition.getBusinessType(), "业务类型不能为空!");
        Long channelId = condition.getChannelId();
        String businessType = condition.getBusinessType();
        //首先根据渠道id获取该合作的所有合同信息
        ChannelBaseInfo baseInfo = channelBaseInfoService.getById(channelId);
        String channelCode = baseInfo.getChannelCode();

        //获取该合作商所有案件列表
        List<CaseChannelInfo> caseChannelInfoList = caseChannelInfoService.list(Wrappers.<CaseChannelInfo>query().lambda()
                .eq(CaseChannelInfo::getDealerNo, channelCode)
        );
        //同步渠道用
        List<ChannelQuotaInfo> channelQuotaInfoList = new ArrayList<>();
        List<FinCostDetails> beforeFinCostDetailsList = new ArrayList<>();
        List<FinCostDetails> signFinCostDetailsList = new ArrayList<>();
        if (caseChannelInfoList.size() > 0) {
            for (CaseChannelInfo caseChannelInfo : caseChannelInfoList) {
                //先放后抵押额度
                CaseContractInfo before = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda()
                        .eq(CaseContractInfo::getApplyNo, caseChannelInfo.getApplyNo())
                        .eq(CaseContractInfo::getBusinessType, businessType)
                        .eq(CaseContractInfo::getQuotaStatus, Constants.QUOTA_OCCUPATION)
                        .eq(CaseContractInfo::getLendingMode, AfsEnumUtil.key(LoanModelEnum.beforeMortgage)));
                //签约放款额度
                CaseContractInfo sign = caseContractInfoService.getOne(Wrappers.<CaseContractInfo>query().lambda()
                        .eq(CaseContractInfo::getApplyNo, caseChannelInfo.getApplyNo())
                        .eq(CaseContractInfo::getBusinessType, businessType)
                        .eq(CaseContractInfo::getQuotaStatus, Constants.QUOTA_OCCUPATION)
                        .eq(CaseContractInfo::getLendingMode, AfsEnumUtil.key(LoanModelEnum.sign)));

                if (before != null) {
                    List<FinCostDetails> beforeFinCostDetails = applyCostDetailsService.list(Wrappers.<FinCostDetails>query().lambda()
                            .eq(FinCostDetails::getApplyNo, before.getApplyNo()));
                    if (beforeFinCostDetails.size() > 0) beforeFinCostDetailsList.addAll(beforeFinCostDetails);
                }
                if (sign != null) {
                    List<FinCostDetails> signFinCostDetails = applyCostDetailsService.list(Wrappers.<FinCostDetails>query().lambda()
                            .eq(FinCostDetails::getApplyNo, sign.getApplyNo()));
                    if (signFinCostDetails.size() > 0) signFinCostDetailsList.addAll(signFinCostDetails);
                }
            }
            if (beforeFinCostDetailsList.size() > 0) {
                //累加先抵后放占用额度
                BigDecimal beforeOccupiedQuota = beforeFinCostDetailsList.stream().map(cost -> cost.getLoanAmt() == null ? BigDecimal.ZERO : cost.getLoanAmt())
                        .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
                ChannelQuotaInfo beforeQuota = channelQuotaInfoService.getOne(Wrappers.<ChannelQuotaInfo>query().lambda()
                        .eq(ChannelQuotaInfo::getBusinessType, businessType)
                        .eq(ChannelQuotaInfo::getChannelId, channelId)
                        .eq(ChannelQuotaInfo::getQuotaType, QuotaTypeEnum.beforeMortgage.getCode())
                );
                BigDecimal quota = beforeQuota.getQuotaAmount() == null ? BigDecimal.ZERO : beforeQuota.getQuotaAmount();
                BigDecimal tempQuota = beforeQuota.getTempQuota() == null ? BigDecimal.ZERO : beforeQuota.getTempQuota();
                beforeQuota.setOccupiedQuota(beforeOccupiedQuota);
                //剩余额度 = 签放额度+临时额度-占用额度
                beforeQuota.setSurplusQuota(quota.add(tempQuota).subtract(beforeOccupiedQuota));
                channelQuotaInfoService.updateById(beforeQuota);
                channelQuotaInfoList.add(beforeQuota);

            }

            if (signFinCostDetailsList.size() > 0) {
                //累加签放占用额度
                BigDecimal signOccupiedQuota = signFinCostDetailsList.stream().map(cost -> cost.getLoanAmt() == null ? BigDecimal.ZERO : cost.getLoanAmt())
                        .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
                ChannelQuotaInfo signQuota = channelQuotaInfoService.getOne(Wrappers.<ChannelQuotaInfo>query().lambda()
                        .eq(ChannelQuotaInfo::getBusinessType, businessType)
                        .eq(ChannelQuotaInfo::getChannelId, channelId)
                        .eq(ChannelQuotaInfo::getQuotaType, QuotaTypeEnum.sign.getCode())
                );
                BigDecimal signQuotaAmount = signQuota.getQuotaAmount() == null ? BigDecimal.ZERO : signQuota.getQuotaAmount();
                BigDecimal signTempQuota = signQuota.getTempQuota() == null ? BigDecimal.ZERO : signQuota.getTempQuota();
                signQuota.setOccupiedQuota(signOccupiedQuota);
                signQuota.setSurplusQuota(signQuotaAmount.add(signTempQuota).subtract(signOccupiedQuota));
                //剩余额度 = 签放额度+临时额度-占用额度
                channelQuotaInfoService.updateById(signQuota);
                channelQuotaInfoList.add(signQuota);
            }
            return channelQuotaInfoList;
        } else {
            //当前合作商没有案件列表,   //剩余额度 = 签放额度+临时额度-占用额度
            List<ChannelQuotaInfo> quotaInfos = channelQuotaInfoService.list(Wrappers.<ChannelQuotaInfo>query().lambda()
                    .eq(ChannelQuotaInfo::getChannelId, channelId)
                    .eq(ChannelQuotaInfo::getBusinessType, businessType)
            );
            if(quotaInfos.size() > 0){
                for (ChannelQuotaInfo quotaInfo : quotaInfos){
                    BigDecimal signQuotaAmount = quotaInfo.getQuotaAmount() == null ? BigDecimal.ZERO : quotaInfo.getQuotaAmount();
                    BigDecimal signTempQuota = quotaInfo.getTempQuota() == null ? BigDecimal.ZERO : quotaInfo.getTempQuota();
                    quotaInfo.setOccupiedQuota(BigDecimal.ZERO);
                    quotaInfo.setSurplusQuota(signQuotaAmount.add(signTempQuota));
                    //剩余额度 = 签放额度+临时额度-占用额度
                    channelQuotaInfoService.updateById(quotaInfo);
                    channelQuotaInfoList.add(quotaInfo);
                }
            }
            return channelQuotaInfoList;
        }
    }
}
